<!--
 * @Description: 树组件
-->
<template>
  <div class="_ehl_tree">
    <slot name="blank0" :data="{ tree, search }"></slot>
    <div v-if="inputShow" class="_ehl_tree_search">
      <ehl-input
        v-if="inputShow"
        :max="max"
        :rows="rows"
        :limit="limit"
        v-model="search"
        :clearable="clearable"
        :placeholder="placeholder"
        :prefix-icon="prefixIcon"
        :suffix-icon="suffixIcon"
        :format="format"
        @enter="onEnter"
        @clear="onClear"
        @change="onInputChange"
    /></div>
    <slot name="blank1" :data="{ tree, search }"></slot>
    <div class="_ehl_tree_all" v-if="(showAll || showTool) && tree && tree.length > 0">
      <span
        class="cpt_btn_ico icon-a-svg17"
        v-if="showAll"
        @click="nodeClick({ label: 'all' })"
      >
        {{ $t('common.quanbu') }}
      </span>
      <span v-if="showTool">
        <span
          v-if="!lazy"
          class="cpt_btn_ico icon-a-svg27"
          @click="setTreeExpand(true)"
          title="展开"
        ></span>
        <span
          v-if="!lazy"
          class="cpt_btn_ico icon-a-svg28"
          @click="setTreeExpand(false)"
          title="收缩"
        ></span>
        <span class="cpt_btn_ico icon-a-svg58" @click="refreshLazy" title="刷新"></span>
      </span>
    </div>
    <div class="_ehl_tree_box" v-if="tree && tree.length > 0">
      <el-tree
        :ref="ref"
        :data="tree"
        :lazy="lazy"
        :props="prop"
        :key="timeFlag"
        :load="loadNode"
        :indent="indent"
        :accordion="accordion"
        :show-checkbox="checkbox"
        :expand-on-click-node="false"
        :node-key="nodeKey || label_p"
        :check-strictly="checkStrictly"
        :filter-node-method="filterNode"
        :highlight-current="highlightCurrent"
        :default-expand-all="defaultExpandAll"
        :check-on-click-node="checkOnClickNode"
        :default-expanded-keys="defaultExpandedKeys"
        @node-click="nodeClick"
        @check-change="checkChange"
        @node-expand="nodeExpand"
        @node-collapse="nodeCollapse"
      >
        <div
          v-if="
            data[isLeafProp] === null ||
            data[isLeafProp] === undefined ||
            (leaf_p !== undefined && leaf_p !== null && data[leaf_p] === true)
          "
          class="_ehl_tree_leaf"
          :title="node[label_p]"
          slot-scope="{ node, data }"
        >
          <slot :name="`tree_leaf`" :data="{ node, data }">
            <div>{{ data[label_p] }}</div>
          </slot>
        </div>
        <div
          v-else
          class="_ehl_tree_root"
          :title="node[label_p]"
          slot-scope="{ node, data }"
        >
          <slot :name="`tree_root`" :data="{ node, data }">
            <div>{{ data[label_p] }}</div>
          </slot>
        </div>
      </el-tree>
    </div>
    <div class="_ehl_tree_nodata" v-else>{{ $t('common.zanwushuju') }}</div>
    <slot name="blank2" :data="{ tree, search }"></slot>
  </div>
</template>
<script>
  import Vue from 'vue'
  import { Tree } from 'element-ui'
  Vue.use(Tree)
  export default {
    props: {
      value: { type: Array, default: () => [] },
      options: {
        type: Array,
        required: true,
        default: () => [],
      },

      //字数最大值
      max: { type: [Number, String], default: () => 50 },
      //显示多少行
      rows: { type: Number, default: () => 1 },
      //是否显示字数
      limit: { type: Boolean, default: () => false },
      //点击节点是否选中
      checkOnClickNode: { type: Boolean, default: () => false },
      //显示清空按钮
      clearable: { type: Boolean, default: () => true },
      //提示语句
      placeholder: { type: String, default: () => 'Enter搜索' },
      //前置图标
      prefixIcon: { type: String, default: () => '' }, //el-icon-search
      //后置图标
      suffixIcon: { type: String, default: () => 'el-icon-search' }, //el-icon-search
      //对于输入框内容的规范
      format: {
        type: Function,
        default: (val, rows) => {
          if (rows === 1) {
            //正则表达式过滤非中文，数字，字母，下划线
            return val.replace(/[^\w\u4e00-\u9fa5\\(\\)-]+/gi, '')
          } else {
            return val
          }
        },
      },

      //是否懒加载
      lazy: { type: Boolean, default: () => false },
      //相邻级节点间的水平缩进
      indent: { type: Number, default: () => 10 },
      //是否开启手风琴模式
      accordion: { type: Boolean, default: () => false },
      //显示选择框
      checkbox: { type: Boolean, default: () => true },
      //唯一判断值
      nodeKey: { type: String, default: () => 'label' },
      //是否遵循父子不互相关联
      checkStrictly: { type: Boolean, default: () => false },
      //是否默认高亮选中
      highlightCurrent: { type: Boolean, default: () => true },
      //树一开始是否全部展开
      defaultExpandAll: { type: Boolean, default: () => true },
      //默认展开的数组
      defaultExpandedKeys: { type: Array, default: () => [] },

      //显示全部按钮
      showAll: { type: Boolean, default: () => false },
      //显示工具按钮
      showTool: { type: Boolean, default: () => false },
      //显示搜索框
      inputShow: { type: Boolean, default: () => true },
      //是否自动记忆上次的值
      autoRemember: { type: Boolean, default: () => false },
      //是否自动勾选
      autoSelect: { type: Boolean, default: () => false },
      //判断是不是子节点依赖的值
      isLeafProp: { type: String, default: () => 'children' },

      prop: {
        type: Object,
        default: () => ({
          label: 'label',
          children: 'children',
          disabled: 'disabled',
          isLeaf: 'leaf',
        }),
      },
      //懒加载函数
      loadNode: {
        type: Function,
        default: (node, resolve) => {},
      },
      //前端根据内容过滤节点
      filterNode: {
        type: Function,
        default: (value, data) => {
          if (!value) return true
          return data.label.indexOf(value) !== -1
        },
      },
    },
    components: { ehlInput: () => $import('ehlInput') },
    data() {
      return {
        ref: `tree_ref_${Math.random()}`,
        search: '',
        tree: this.options,
        label_p: this.prop['label'],
        children_p: this.prop['children'],
        leaf_p: this.prop['isLeaf'],
        oldInNew: [],
        timeFlag: new Date().getTime(),
      }
    },
    watch: {
      options() {
        this.autoSelect && this.setSelect(this.value)
      },
    },
    mounted() {
      this.$emit('init', this.tree)
      this.autoSelect && this.setSelect(this.value)
    },
    methods: {
      ssss(data) {
        debugger
      },
      //非内部勾选，外部更改了选项值之后需要调用
      setSelect(arr) {
        this.$nextTick(() => {
          if (this.checkbox && this.$refs[this.ref]) {
            this.$refs[this.ref].setCheckedNodes(arr)
            this.oldInNew = JSON.parse(
              JSON.stringify(this.$refs[this.ref].getCheckedNodes() || []),
            )
          }
        })
      },
      //获取当前选中值
      getSelectItem() {
        return this.$refs[this.ref].getCheckedNodes()
      },
      //获取当前树的结构对象
      getTree() {
        return this.$refs[this.ref].data
      },
      //设置当前高亮node，为null则取消高亮
      setCurrentKey(key) {
        this.$refs[this.ref].setCurrentKey(key)
      },
      //全部展开或者收缩，expand=true or false
      setTreeExpand(expand) {
        let nodes = this.$refs[this.ref].store.nodesMap
        for (const i in nodes) {
          nodes[i].expanded = expand
        }
      },
      //获取上部搜索框的值
      getSearchTxt() {
        return this.search || ''
      },
      //清除上部搜索框的值
      clearSearchTxt() {
        this.search = ''
      },
      //全选或者全不选
      checkAll(val) {
        if (val) {
          this.$refs[this.ref].setCheckedNodes(this.tree)
        } else {
          this.$refs[this.ref].setCheckedNodes([])
        }
      },
      onInputChange(val) {
        this.$emit('txt-change', this.tree, val)
      },
      onEnter(val) {
        this.$emit('enter', this.tree, val)
      },
      onClear(val) {
        this.$emit('clear', this.tree, val)
      },
      nodeClick(node) {
        if (node.label === 'all') {
          this.$refs[this.ref].setCheckedNodes([])
        }
        this.$emit('node-click', node)
        if (!this.checkbox) {
          //不是勾选模式的情况下，绑定值更新为当前点击的值
          this.$emit('input', [node])
        }
      },
      checkChange(data, checked, indeterminate) {
        let that = this
        that.$nextTick(() => {
          if (that.$refs[that.ref]) {
            let checkedNodes = that.$refs[that.ref].getCheckedNodes()
            if (this.autoRemember) {
              //遍历以前的值在当前复现的，对比选中后的数组，没有的删除
              that.oldInNew.forEach(i => {
                let res = checkedNodes.find(ii => {
                  return ii[that.nodeKey] === i[that.nodeKey]
                })
                if (!res) {
                  // console.log('要删除-' + i[that.nodeKey])
                  let tmp = []
                  that.value.forEach(iii => {
                    if (iii[that.nodeKey] !== i[that.nodeKey]) {
                      tmp.push(iii)
                    }
                  })
                  that.value.clearAll()
                  tmp.forEach(iiii => {
                    that.value.push(iiii)
                  })
                  // console.log(
                  //   '删除后-' +
                  //     that.value
                  //       .map(t => {
                  //         return t[that.nodeKey]
                  //       })
                  //       .join(','),
                  // )
                }
              })
              //遍历以当前选中的值，对比以前值在当前复现的，没有的添加
              checkedNodes.forEach(i => {
                let res = that.oldInNew.find(ii => {
                  return ii[that.nodeKey] === i[that.nodeKey]
                })
                if (!res) {
                  //只添加子，所有根不添加，这块值得商榷
                  !i[that.children_p] && that.value.push(i)
                  that.value.clearRepeat(that.nodeKey)
                  // console.log('要添加-' + i[that.nodeKey])
                }
                // console.log(
                //   '添加后-' +
                //     that.value
                //       .map(t => {
                //         return t[that.nodeKey]
                //       })
                //       .join(','),
                // )
              })
              that.$emit('input', that.value)
              that.setSelect(that.value)
            } else {
              that.$emit('input', checkedNodes)
            }
          }
        })
      },
      //节点展开
      nodeExpand(data, node) {
        this.$emit('node-expand', data, node)
      },
      //节点关闭
      nodeCollapse(data, node) {
        this.$emit('node-collapse', data, node)
      },
      refreshLazy() {
        this.timeFlag = new Date().getTime()
      },
    },
  }
</script>
